package com.insight.modules.util;

import com.insight.modules.system.mapper.UtilsMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author wangruheng
 * @title: CodeUtils
 * @projectName ledger-boot-parent
 * @description: 获取编码的工具类
 * @date 2020/9/1416:04
 */
@Component
public class CodeUtils {

    @Autowired
    private UtilsMapper utilsMapper;

    /**
     * 获取编码，格式为 prefix + yyyyMMdd + 4位流水号
     * 例如：前缀 "ORD" + 20250717 + 0001 -> ORD202507170001
     *
     * @param prefix    编码前缀
     * @param tableName 表名
     * @param codeField 字段名（存放编码的字段）
     * @return 生成的编码字符串
     */
    public String getCode(String prefix, String tableName, String codeField){
        // 获取当前日期字符串，格式 yyyyMMdd
        SimpleDateFormat f = new SimpleDateFormat("yyyyMMdd");
        String date = f.format(new Date(System.currentTimeMillis()));

        // 拼接SQL，查询当天该前缀下的所有编码，按编码降序排序，取最大值
        // SQL 示例: select codeField from tableName where codeField like 'prefix+date%' order by codeField desc
        StringBuilder sql = new StringBuilder("select ");
        sql.append(codeField).append(" from ").append(tableName).append(" where ").append(codeField);
        sql.append(" like '").append(prefix).append(date).append("%' order by ").append(codeField).append(" desc");

        // 调用mapper执行SQL，获取编码列表，第一条即最大编码
        List<String> codes = utilsMapper.getCode(sql.toString());

        String code;
        if (codes.size() > 0) {
            // 取最大编码
            String maxCode = codes.get(0);
            // 截取日期后面的流水号部分（假设前缀长度+8位日期后是流水号）
            // 这里假设流水号从第10位开始，比如 ORD202507170001，从第10位开始截取 0001
            String numberPart = maxCode.substring(prefix.length() + date.length());
            int intNumber = Integer.parseInt(numberPart);
            intNumber = Math.addExact(intNumber, 1); // 流水号加1

            // 补全流水号为4位，不足左侧补0
            StringBuilder sb = new StringBuilder(String.valueOf(intNumber));
            while (sb.length() < 4) {
                sb.insert(0, '0');
            }

            code = prefix + date + sb.toString();
        } else {
            // 当天无编码，流水号从0001开始
            code = prefix + date + "0001";
        }

        return code;
    }
}

